﻿using Xejen.Hosting;
using Xejen.Logger;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;

namespace Xejen.Framework.Test
{
    public partial class MainForm : Form
    {
        private readonly ILogger _logger;
        private readonly IEventBus<string> _eventBus;
        public MainForm(IAppHost appHost, ILoggerManager loggerManager, Form1 form1)
        {
            _logger = loggerManager.CreateLogger<ILogger<MainForm>>();//只有这个日志生效，另外 2种写法实际没有写到日志
            InitializeComponent();

            IEventBus<string> eventBus = new InMemoryEventBus<string>();
            eventBus.Subscribe<string>("EventType1", OnJobDataWrittenCompleted);

            _eventBus = eventBus;
        }

        private void OnJobDataWrittenCompleted(EventMessage<string, string> eventMessage)
        {
            MessageBox.Show(eventMessage.EventData);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            var a = "".ToBase64();
            var b = "fdas:fasd2323".ToBase64();
            var c = "dab".ToBase64();

            var a1 = a.FromBase64();
            var b1 = b.FromBase64();
            var c1 = c.FromBase64();

            _logger.LogInformation($"完成界面加载：{{@value}}", new { Name = "马志远", Value = "富了帅了" });
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form1 form = new Form1();
            form.Show();
        }

        /// <summary>
        /// 日期格式化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            var model = new { DateTime = DateTime.Now, Name = "mazhiyuan", Age = 40, Yesterday = (DateTime?)null };

            JsonSerializerOptions options = new JsonSerializerOptions
            {
                WriteIndented = false,
                PropertyNameCaseInsensitive = false,
                Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                Converters = { new System.Text.Json.Serialization.DateTimeConverter("yyyy-MM-dd HH:mm:ss"), new System.Text.Json.Serialization.DateTimeNullableConverter("yyyy-MM-dd HH:mm:ss") },
            };
            var json = System.Text.Json.JsonSerializer.Serialize(model, options);

            MessageBox.Show(json);
        }

        /// <summary>
        /// 模拟鼠标点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            // 获取隐藏在背后的Form1窗体句柄
            IntPtr hWndForm1 = new IntPtr(Convert.ToInt32("000103E0", 16));  //new IntPtr(Convert.ToInt32("00B70D58", 16)); // FindWindow("WeChatMainWndForPC", null);//

            if (hWndForm1 == IntPtr.Zero)
            {
                MessageBox.Show("未找到目标窗体");
                return;
            }



            //// 获取Form1中按钮的句柄（假设按钮的Name为button1）
            //IntPtr hWndButton = FindWindowEx(hWndForm1, IntPtr.Zero, null, "button1");
            //if (hWndButton == IntPtr.Zero)
            //{
            //    MessageBox.Show("未找到Form1中的按钮");
            //    return;
            //}
            //hWndForm1 = hWndButton;

            //SetForegroundWindow(hWndForm1);





            // 获取Form1窗口的位置
            GetWindowRect(hWndForm1, out RECT rect);
            // 计算点击位置相对于Form1的坐标
            int x = 126;// 232;// 308;//  //后台窗体的相对坐标，不是整个屏幕中的绝对坐标
            int y = 587;//156// 190;// 96;//  //后台窗体的相对坐标，不是整个屏幕中的绝对坐标

            // User32.SetCursorPos(x, y);

            // 将x, y坐标转换为一个LPARAM值
            IntPtr lParam = (IntPtr)((y << 16) | (x & 0xFFFF));
            //lParam = new IntPtr(x + (y << 16)); //X坐标为低位，Y坐标为高位

            //// 发送鼠标左键按下和释放消息
            //SendMessage(hWndForm1, WM_LBUTTONDOWN, IntPtr.Zero, lParam);
            //SendMessage(hWndForm1, WM_LBUTTONUP, IntPtr.Zero, lParam);


            // 遍历Form1的所有子窗口句柄
            List<IntPtr> childWindows = new List<IntPtr>();
            EnumChildWindows(hWndForm1, (hwnd, lParam1) =>
            {
                //StringBuilder className = new StringBuilder(256);
                //GetClassName(hwnd, className, className.Capacity);

                //StringBuilder windowText = new StringBuilder(256);
                //GetWindowText(hwnd, windowText, windowText.Capacity);

                //// 打印类名和窗口名，帮助你确定哪个窗口是程序
                //Debug.WriteLine($"窗口句柄: {hwnd}, 类名: {className}, 窗口名: {windowText}");

                //// 假设你找到了目标程序窗口句柄
                //// 在这里你可以根据实际条件来判断，并发送点击消息
                //if (className.ToString() == "目标窗口类名") // 用实际找到的类名替换
                //{
                //    // 模拟点击
                //    SendMessage(hwnd, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
                //    SendMessage(hwnd, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
                //    Debug.WriteLine("已模拟点击！");
                //    return false; // 返回false停止枚举
                //}

                childWindows.Add(hwnd);
                return true; // 返回true继续枚举，返回false停止枚举
            }, IntPtr.Zero);
            foreach (IntPtr hWndButton in childWindows)
            {
                // 获取窗口标题
                StringBuilder sb = new StringBuilder(256);
                GetWindowText(hWndButton, sb, sb.Capacity);
                string windowText = sb.ToString();

                // 你可以根据窗口标题或其他条件检查是否是目标按钮
                //if (windowText == "button1") // 假设你知道按钮的标题
                //{
                //// 发送鼠标左键按下消息
                //SendMessage(hWndButton, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
                //// 发送鼠标左键抬起消息
                //SendMessage(hWndButton, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);

                PostMessage(hWndButton, WM_LBUTTONDOWN, IntPtr.Zero, lParam);
                PostMessage(hWndButton, WM_LBUTTONUP, IntPtr.Zero, lParam);
                //break;
                //}
            }

            //也可以使用 PostMessage 来异步发送消息
            PostMessage(hWndForm1, WM_MOUSEMOVE, IntPtr.Zero, lParam);
            PostMessage(hWndForm1, WM_LBUTTONDOWN, IntPtr.Zero, lParam);
            PostMessage(hWndForm1, WM_LBUTTONUP, IntPtr.Zero, lParam);
            //PostMessage(hWndForm1, (int)WM_LBUTTONDOWN, 1, x + (y << 16));
            //PostMessage(hWndForm1, (int)WM_LBUTTONUP, 1, x + (y << 16));

            ////------------下面代码可以触发
            //// 发送鼠标左键按下消息
            //SendMessage(hWndButton, WM_LBUTTONDOWN, IntPtr.Zero, IntPtr.Zero);
            //// 发送鼠标左键抬起消息
            //SendMessage(hWndButton, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
        }

        // 将两个16位整数转换为一个LPARAM值
        private IntPtr MakeLParam(int lowWord, int highWord)
        {
            return (IntPtr)((highWord << 16) | (lowWord & 0xFFFF));
        }

        // 定义鼠标点击的消息常量
        private const int BM_CLICK = 0x00F5;

        // 定义SendMessage函数的外部引用
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        // 导入Win32 API
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("user32.dll")]
        private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        private static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
        [DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
        private static extern void SetForegroundWindow(IntPtr hwnd);

        [DllImport("user32.dll")]
        private static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildProc lpEnumFunc, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);


        private const uint WM_LBUTTONDOWN = 0x0201;
        private const uint WM_LBUTTONUP = 0x0202;

        // 委托声明，用于EnumChildWindows回调
        private delegate bool EnumChildProc(IntPtr hwnd, IntPtr lParam);


        [StructLayout(LayoutKind.Sequential)]
        private struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        [DllImport("user32")]
        public static extern void PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

        const int WM_MOUSEMOVE = 0x200;//移动鼠标时发生，同WM_MOUSEFIRST  

        private void button2_Click(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 测试事件总线
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            _eventBus.Publish<string>(new EventMessage<string, string>("EventType1", "中国人就是牛B class"));
        }
    }
}
